package ch.netcetera.planningpoker.client.ui.admin.round;

import java.util.logging.Logger;

import ch.netcetera.planningpoker.client.model.RoundProxy;
import ch.netcetera.planningpoker.client.ui.events.RoundStatusChangedEvent;
import ch.netcetera.planningpoker.client.ui.events.RoundStatusChangedEventHandler;
import ch.netcetera.planningpoker.client.ui.participant.create.CreateParticipantPresenter;
import ch.netcetera.planningpoker.client.ui.round.RoundPresenter;
import ch.netcetera.planningpoker.shared.GameRequestFactory;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.View;
import com.gwtplatform.mvp.client.annotations.ProxyStandard;
import com.gwtplatform.mvp.client.proxy.Proxy;

public class ModeratorRoundPresenter
        extends
        Presenter<ModeratorRoundPresenter.IView, ModeratorRoundPresenter.IProxy> {

    private static final Logger logger = Logger
            .getLogger(CreateParticipantPresenter.class.getName());

    public static final String NAME_TOKEN = "participant";
    public static final String ARG_GAME_ID = "gameId";
    public static final String ARG_GAME_NAME = "gameName";

    @ProxyStandard
    public interface IProxy extends Proxy<ModeratorRoundPresenter> {

    }

    public interface IView extends View {

        HasText getRoundTitle();

        HasClickHandlers getCreate();

        HasClickHandlers getCloseRound();

        void setOpenRoundVisible(boolean isOpenRoundVisible);
        
        HasWidgets getCurrentRound();
    }

    private GameRequestFactory requestFactory;

    private Long gameId;

    private Long currentRoundId;

    private RoundPresenter roundPresenter;

    @Inject
    public ModeratorRoundPresenter(EventBus eventBus, IView view, IProxy proxy,
            GameRequestFactory requestFactory, RoundPresenter roundPresenter) {
        super(eventBus, view, proxy);
        this.requestFactory = requestFactory;
        this.roundPresenter = roundPresenter;
    }

    @Override
    protected void onBind() {
        getView().getCurrentRound().add(roundPresenter.getWidget());
        getView().getCreate().addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                createNewRound();
            }
        });
        getView().getCloseRound().addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                closeCurrentRound();
            }
        });
        getEventBus().addHandler(RoundStatusChangedEvent.TYPE, new RoundStatusChangedEventHandler() {
            
            @Override
            public void onRoundStatusChanged(RoundStatusChangedEvent event) {
                logger.info("Seems like the round status changed. Lets load the round for game " + event.getGameId());
                loadRound(event.getGameId());
            }
        });
    }

    protected void closeCurrentRound() {
        logger.info("Close round " + currentRoundId);
        requestFactory.getRoundRequest().closeRound(currentRoundId).fire(new Receiver<Void>() {

            @Override
            public void onSuccess(Void response) {
                getEventBus().fireEventFromSource(new RoundStatusChangedEvent(gameId), this);
            }
        });
    }

    private void loadRound(Long gameId) {
        this.gameId = gameId;
        requestFactory.getRoundRequest().getOpenRoundForGame(gameId)
                .fire(new Receiver<RoundProxy>() {

                    @Override
                    public void onSuccess(RoundProxy currentRound) {
                        logger.info("Got open round: " + currentRound);
                        displayOpenRound(currentRound);
                    }
                });
    }

    protected void createNewRound() {
        String roundTitle = getView().getRoundTitle().getText();
        // validate round title if necessary
        requestFactory.getRoundRequest().createRoundForGame(roundTitle, gameId)
                .fire(new Receiver<RoundProxy>() {

                    @Override
                    public void onSuccess(RoundProxy response) {
                        displayOpenRound(response);
                        getEventBus().fireEventFromSource(new RoundStatusChangedEvent(gameId), this);
                    }
                });
    }

    protected void displayOpenRound(RoundProxy currentRound) {
        getView().setOpenRoundVisible(currentRound == null);
        if (currentRound!= null) {
            this.currentRoundId = currentRound.getId();
        }
    }

    @Override
    protected void revealInParent() {

    }
}
